﻿#ifndef PLC_INTERFACE_BASE_H
#define PLC_INTERFACE_BASE_H

//Basic
#include <QByteArray>
#include <QObject>

//Demand
#include "CommunicationType.h"
#include "CommunicationProtocol.h"

class PLC_Interface_Base
#ifndef QT_NO_QOBJECT
    : public QObject
#endif
{
#ifndef QT_NO_QOBJECT
    Q_OBJECT
#endif
public:
    PLC_Interface_Base(CommunicationType type, CommunicationProtocol protocal) : commuType(type), commuProtocal(protocal){}
    virtual ~PLC_Interface_Base(){}

public:
    //连接函数
    /* 返回：true：连接成功
     *      false：连接失败
     * */
    virtual bool Connect() = 0;

    //断开连接函数
    /* 返回：void
     * */
    virtual void DisConnect() = 0;

    //报文发送函数
    /* 参数： 发送报文的引用
     * 返回：1：发送成功，响应成功
     *      0：发送成功，响应失败
     * */
    virtual int MessageSend(const QByteArray &arr){return 0;};

    //报文接收函数
    /* 参数：存储报文的数组
     * 返回：true：接收成功
     *      false：接收失败
     * */
    virtual bool MessageReceive(QByteArray &arr){return false;};

public:
    //十六进制数组转十六进制字符串
    /*1.
     * 参数1：目标十六进制数组
     * 参数2：需要转化的长度
     * 参数3：连接后的十六进制字符串引用
     * 返回：void
     * */
    void HexByteArrayToHexString(const QByteArray &hexByteArr, int convertLen, QString &str);
    /*2.
     * 参数1：目标十六进制数组
     * 参数2：需要转化的长度
     * 返回：连接后的十六进制字符串
    **/
    QString HexByteArrayToHexString(const QByteArray &hexByteArr, int convertLen);

    //CRC校验码计算函数
    /*1.
     * 参数1：需要计算CRC的目标字符串
     * 参数2：目标CRC字符串引用
     * 返回：void
     * */
    void CalculateCRC(const QString &checkStr, QString &checkStrCrc);
    /*2.
     * 参数1：需要计算CRC的目标字符串
     * 返回：CRC校验码字符串
     * */
    QString CalculateCRC(const QString &checkStr);

    //判断报文CRC正确性函数
    /*1.
     * 参数1：目标字节数组
     * 返回：true：CRC校验通过
     *      false：CRC校验失败
     * */
    bool JudgeCRC(const QByteArray &arr);
    /*2.
     * 参数1：目标字节数组
     * 参数2：正确的CRC校验码
     * 返回：true：CRC校验通过
     *      false：CRC校验失败
     * */
    bool JudgeCRC(const QByteArray &arr, const QString &crc);

    //为任意报文数组末尾添加CRC检验并返回
    /* 参数：需要添加CRC校验码的字节数组
     * 返回：void
     * */
    void AddCRCToByteArray(QByteArray &arr);

    //连接两个quint8数据为一个quint16数据
    /* 1.
     * 参数1：前quint8数据引用
     * 参数2：后quint8数据引用
     * 返回：连接后quint16数据
     * */
    quint16 BondTwoUint8ToUint16(const quint8 &preNum, const quint8 &laterNum);
    /*2.
     * 参数1：前quint8数据
     * 参数2：后quint8数据
     * 参数3：连接后quint16数据引用
     * 返回：void
     * */
    void BondTwoUint8ToUint16(const quint8 &preNum, const quint8 &laterNum, quint16 &bondNum);

    //字节反转函数
    /* 参数：需要翻转的8位字节字符串
     * 返回：true：反转成功
     *      false：反转失败
     * */
    bool ByteReverse(QString &str);

public:
    //返回当前串口类型函数
    CommunicationType GetCommunicationType();
    //返回当前通讯协议类型函数
    CommunicationProtocol GetCommunicationProtocol();

    //获取当前请求报文数组
    /*1.
     * 参数：接收数组容器
     * 返回：void
     * */
    void GetRequestMessage(QByteArray &requestMess);
    /*2.
     * 参数：空
     * 返回：当前请求报文数组
     * */
    QByteArray GetRequestMessage();

    //获取当前接收报文数组
    /*1.
     * 参数：接收数组容器
     * 返回：void
     * */
    void GetReceiveMessage(QByteArray &receiveMess);
    /*2.
     * 参数：空
     * 返回：当前请接收报文数组
     * */
    QByteArray GetReceiveMessage();

protected:
    //请求报文数组
    QByteArray RequestMessage;
    //接收报文数组
    QByteArray ReceiveMessage;

    //串口类型
    CommunicationType commuType;
    //通讯协议类型
    CommunicationProtocol commuProtocal;
};

#endif // PLC_INTERFACE_BASE_H
